<?php

namespace app\admin\service;

use app\admin\dao\MemberDao;
use app\admin\model\UM as UM;
use app\admin\service\traits\TuTrait;
use app\admin\traits\StatisticsTrait;
use app\common\model\AccessLog;
use app\common\model\Area;
use app\common\model\LogCaptcha;
use app\common\model\Member;
use app\common\model\MemberInfo;
use app\common\model\Trade;
use ShidianUtil\Utils\TimeUtil;
use think\facade\Db;

/**
 * Class MemberStatisticsService
 * @package app\member\service
 */
class MemberStatisticsService
{
    use TuTrait;
    use StatisticsTrait;

    private MemberDao $memberDao;

    public function __construct(MemberDao $memberDao)
    {
        $this->memberDao = $memberDao;
    }


    /**
     * 用户列表-统计
     * @param UM|null $user
     * @param $channel
     * @param $chain
     * @param $provinceId
     * @param $cityId
     * @param $startTime
     * @param $endTime
     * @param $kw
     * @param $inviteId
     * @return array
     * @throws \think\db\exception\DbException
     */
    public function read(?UM $user, $channel, $chain, $provinceId, $cityId, $startTime, $endTime, $kw, $inviteId): array
    {
        if (is_numeric($endTime)) {
            $endTime = TimeUtil::stamp(TimeUtil::DAY, $endTime, false);
        }
        return $this->memberDao->statisticsListMembers($channel, $chain, $provinceId, $cityId, $startTime, $endTime, $kw, $inviteId);
    }

    /**
     * 数据页面-用户统计
     * @param array $params
     * @return array
     */
    public function readOfData(array $params): array
    {
        $now = time();

        $params['startTime'] ??= $now;
        // $startTime = TimeUtil::stamp(TimeUtil::DAY, $params['startTime']);
        $startTime = $params['startTime'];

        $params['endTime'] ??= $now;
        // $endTime = TimeUtil::stamp(TimeUtil::DAY, $params['endTime'], false);
        $endTime = $params['endTime'];
        if (is_numeric($endTime)) {
            $endTime = TimeUtil::stamp(TimeUtil::DAY, $endTime, false);
        }

        return [
            'datas' => $this->readDatas($startTime, $endTime),
            'tu' => $this->readTu($startTime, $endTime),
            'paihang' => $this->readPaihang($startTime, $endTime),
        ];
    }

    private function readDatas($startTime, $endTime): array
    {

        // PV
        $pv = AccessLog::timeRange($startTime, $endTime, 'created', 'created')
            ->count();

        // UV
        $uv = AccessLog::timeRange($startTime, $endTime, 'created', 'created')
            ->group('ip')
            ->count();

        // 登录用户
        $login_member_count = AccessLog::timeRange($startTime, $endTime, 'created', 'created')
            ->where('memberId', '<>', '0')
            ->group('memberId')
            ->count();

        // 普通用户
        $member_count = Member::where('created', '<=', $endTime)->where('type', 0)->count();

        // 律师总数
        $lawyer_count = Member::where('created', '<=', $endTime)->where('type', 1)->count();

        // 推广者
        $inviter_count = Member::where('inviterTime', '<=', $endTime)->where('isInviter', 1)->count();

        // 新增用户
        $new_member_count = Member::timeRange($startTime, $endTime, 'created', 'created')->count();

        // 注册率
        $regist_rate = show_percentage($new_member_count, $uv, 2, '0%');

        // 验证码数
        $captcha_count = LogCaptcha::timeRange($startTime, $endTime, 'created', 'created')
            ->where('scene', CAPTCHA_DENGLU)
            ->group('phone')
            ->count();

        // 留资率 = 提问人数 / 新增用户数
        $consultingCount = $this->questionMemberNum($startTime, $endTime);
        $newMemberCount = Member::timeRange($startTime, $endTime, 'created', 'created')->count();
        $liuzi = show_percentage($consultingCount, $newMemberCount, 2, '0%');

        // 支付率
        $payCount = Trade::timeRange($startTime, $endTime, 'created', 'created')
            ->where('payStatus', Trade::PAID)
            ->consultingTrade()
            ->count();
        $loginCount = AccessLog::timeRange($startTime, $endTime, 'created', 'created')
            ->where('memberId', '<>', '0')
            ->group('memberId')
            ->count();
        $payRate = show_percentage($payCount, $loginCount, 2, '0%');

        return [
            ['dataIconImg' => image_url('/storage/static/images/a1/t1.png', 'min'), 'name' => 'PV', 'value' => $pv],
            ['dataIconImg' => image_url('/storage/static/images/a1/t2.png', 'min'), 'name' => 'UV', 'value' => $uv],
            ['dataIconImg' => image_url('/storage/static/images/a1/t3.png', 'min'), 'name' => '登录用户', 'value' => $login_member_count],
            ['dataIconImg' => image_url('/storage/static/images/a1/t4.png', 'min'), 'name' => '普通用户', 'value' => $member_count],
            ['dataIconImg' => image_url('/storage/static/images/a1/t5.png', 'min'), 'name' => '律师总数', 'value' => $lawyer_count],
            ['dataIconImg' => image_url('/storage/static/images/a1/t6.png', 'min'), 'name' => '推广者', 'value' => $inviter_count],
            ['dataIconImg' => image_url('/storage/static/images/a1/t7.png', 'min'), 'name' => '新增用户', 'value' => $new_member_count],
            ['dataIconImg' => image_url('/storage/static/images/a1/sms.png', 'min'), 'name' => '短信数', 'value' => $captcha_count],
            ['dataIconImg' => image_url('/storage/static/images/a1/t8.png', 'min'), 'name' => '注册率', 'value' => $regist_rate],
            ['dataIconImg' => image_url('/storage/static/images/data/7.png', 'min'), 'name' => '留资率', 'value' => $liuzi,],
            ['dataIconImg' => image_url('/storage/static/images/data/15.png', 'min'), 'name' => '支付率', 'value' => $payRate,],
        ];
    }

    private function readTu($startTime, $endTime): array
    {
        $min = 7 * 86400 - 1;
        if ($endTime - $startTime < $min) {
            $startTime = $endTime - $min;
        }

        $startDate = date('Y-m-d', $startTime);
        $endDate = date('Y-m-d', $endTime);

        $times = $this->getTimes($startTime, $endTime);

        // PV （每天的PV）
        $accessLog = AccessLog::getTable();
        $sql = "SELECT `date`, count(*) AS `value` FROM `$accessLog` WHERE `date` >= :startDate AND `date` <= :endDate GROUP BY `date`";
        $pv = Db::query($sql, ['startDate' => $startDate, 'endDate' => $endDate]);
        $pv = array_column($pv, 'value', 'date');
        $pv = $this->wrapTuItem($times, $pv);

        // UV
        $sql = "SELECT `date`, count(*) AS `value` FROM	( SELECT `date`, `ip` FROM `$accessLog` WHERE `date` >= :startDate AND `date` <= :endDate GROUP BY `date`, `ip` ) tmp GROUP BY `date`";
        $uv = Db::query($sql, ['startDate' => $startDate, 'endDate' => $endDate]);
        $uv = array_column($uv, 'value', 'date');
        $uv = $this->wrapTuItem($times, $uv);

        // 新增用户
        $sql = "SELECT FROM_UNIXTIME(created,'%Y-%m-%d') as `date`, count(*) as `value` from ls_member where created >= :startTime AND created <= :endTime group by `date`";
        $new_count = Db::query($sql, ['startTime' => $startTime, 'endTime' => $endTime]);
        $new_count = array_column($new_count, 'value', 'date');
        $new_count = $this->wrapTuItem($times, $new_count);

        // 新增律师
        // $sql = "SELECT FROM_UNIXTIME( ls_member_info.created, '%Y-%m-%d' ) AS `date`, count(*) AS `value` FROM ls_member LEFT JOIN ls_member_info ON ls_member.id = ls_member_info.memberId WHERE ls_member.type = 1 AND ls_member_info.created >= :startTime AND ls_member_info.created <= :endTime group by `date`";
        // $new_lawyer_count = Db::query($sql, ['startTime' => $startTime, 'endTime' => $endTime]);
        // $new_lawyer_count = array_column($new_lawyer_count, 'value', 'date');
        // $new_lawyer_count = $this->wrapTuItem($times, $new_lawyer_count);

        // 登录总数
        // $sql = "SELECT `date`, count(*) AS `value` FROM	( SELECT `date`, `memberId` FROM `ls_access_log` WHERE created >= :startTime AND created <= :endTime AND memberId <> 0 GROUP BY `date`, `memberId` ) tmp GROUP BY `date`";
        // $login_member_count = Db::query($sql, ['startTime' => $startTime, 'endTime' => $endTime]);
        // $login_member_count = array_column($login_member_count, 'value', 'date');
        // $login_member_count = $this->wrapTuItem($times, $login_member_count);

        // 在线律师数
        // $member = Member::getTable();
        // $sql = "SELECT `date`, count(*) AS `value` FROM	( SELECT `date`, `memberId` FROM `$accessLog` WHERE created >= :startTime AND created <= :endTime AND memberId <> 0 GROUP BY `date`, `memberId` ) tmp left join `$member` on tmp.memberId=`$member`.id where `$member`.type =1 GROUP BY `date`";
        // $login_lawyer_count = Db::query($sql, ['startTime' => $startTime, 'endTime' => $endTime]);
        // $login_lawyer_count = array_column($login_lawyer_count, 'value', 'date');
        // $login_lawyer_count = $this->wrapTuItem($times, $login_lawyer_count);

        // return [
        //     'data' => [
        //         ['name' => 'UV', 'data' => [120, 132, 101, 134, 90, 230, mt_rand(100, 999)], 'color' => '#EBC312',],
        //         ['name' => '登录总数', 'data' => [220, 182, 191, 234, 290, 330, mt_rand(100, 999)], 'color' => '#F88135',],
        //         ['name' => '律师在线', 'data' => [150, 232, 201, 154, 190, 330, mt_rand(100, 999)], 'color' => '#438AFF',],
        //     ],
        //     'x' => ['12/04', '12/05', '12/06', '12/07', '12/08', '12/09', '12/10',]
        // ];

        return [
            'data' => [
                ['name' => 'PV', 'data' => $pv, 'color' => '#EBC312'],
                ['name' => 'UV', 'data' => $uv, 'color' => '#F88135'],
                ['name' => '新增用户', 'data' => $new_count, 'color' => '#3970EF'],
                // ['name' => '新增律师', 'data' => $new_lawyer_count, 'color' => '#EBC312'],
                // ['name' => '登录总数', 'data' => $login_member_count, 'color' => '#F88135'],
                // ['name' => '律师在线', 'data' => $login_lawyer_count, 'color' => '#438AFF'],
            ],
            'x' => $this->getX($times),
        ];
    }

    private function readPaihang($startTime, $endTime, $number = 7): array
    {
        // 每个城市 在某天截止的 普通用户数 律师数 推广者数量
        $memebr = Member::getTable();
        $memberInfo = MemberInfo::getTable();
        $area = Area::getTable();
        $subSql = "SELECT cityId, SUM(IF (type=0,1,0)) AS member_count, SUM(IF (isInviter=1,1,0)) AS inviter_count FROM `$memebr` WHERE `$memebr`.created <= $endTime GROUP BY cityId";
        $subSql1 = "SELECT cityId, count(*) AS lawyer_count FROM `$memberInfo` WHERE `$memberInfo`.created <= $endTime GROUP BY cityId";
        $sql = "SELECT `$area`.id,`$area`.name, tmp.member_count, tmp1.lawyer_count, tmp.inviter_count FROM `$area` LEFT JOIN ($subSql) tmp ON `$area`.id=tmp.cityId LEFT JOIN ($subSql1) tmp1 ON `$area`.id=tmp1.cityId  WHERE pid<> 0 AND city=0 ORDER BY tmp.member_count DESC limit $number";
        $result = Db::query($sql);
        foreach ($result as $k => $item) {
            $result[$k]['member_count'] ??= 0;
            $result[$k]['lawyer_count'] ??= 0;
            $result[$k]['inviter_count'] ??= 0;
        }
        return $result;
    }
}
